package com.code2roc.fastboot.system.codegen.controller;

import com.code2roc.fastboot.framework.util.CommonUtil;
import com.code2roc.fastboot.framework.util.FileUtil;
import com.code2roc.fastboot.system.codegen.bizlogic.CodeGenLogic;
import com.code2roc.fastboot.system.codegen.model.DataBaseTableInfo;
import com.code2roc.fastboot.system.codegen.model.SystemTableDO;
import com.code2roc.fastboot.system.codegen.service.ISystemTableService;
import com.code2roc.fastboot.model.BaseBootController;
import com.code2roc.fastboot.framework.database.CommonDTO;
import com.code2roc.fastboot.framework.model.Result;
import com.code2roc.fastboot.framework.util.ConvertOp;
import com.code2roc.fastboot.framework.util.StringUtil;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.transaction.annotation.Isolation;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;

import javax.servlet.http.HttpServletRequest;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

@RestController
@RequestMapping("/system/codegen")
public class CodeGenController extends BaseBootController {
    @Autowired
    private CodeGenLogic codeGenLogic;
    @Autowired
    private CommonDTO commonDTO;
    @Autowired
    private ISystemTableService tableService;

    @ResponseBody
    @PostMapping("/getImportTableList")
    public Object list(@RequestBody Map<String, Object> params) {
        Result result = Result.okResult();
        HashMap paramMap = new HashMap();
        String table_name = ConvertOp.convert2String(params.get("table_name"));
        String table_comment = ConvertOp.convert2String(params.get("table_comment"));
        String sql = "table_schema = #{table_schema}";
        paramMap.put("table_schema", codeGenLogic.getSchemaName());
        if (!StringUtil.isEmpty(table_name)) {
            sql += "and table_name like #{table_name}";
            paramMap.put("table_name", "%" + table_name + "%");
        }
        if (!StringUtil.isEmpty(table_comment)) {
            sql += "and table_comment like #{table_comment}";
            paramMap.put("table_comment", "%" + table_comment + "%");
        }
        List<SystemTableDO> tableDOList = tableService.selectAllList();
        String guidString = "";
        List<String> guidList = tableDOList.stream().map(a -> a.getTable_name()).distinct().collect(Collectors.toList());
        if (guidList.size() == 0) {
            guidString = "''";
        } else {
            for (int i = 0; i < guidList.size(); i++) {
                if (i == guidList.size() - 1) {
                    guidString += "'" + guidList.get(i) + "'";
                } else {
                    guidString += "'" + guidList.get(i) + "',";
                }
            }
        }
        sql += " and table_name not in (" + guidString + ")";
        List<DataBaseTableInfo> rows = commonDTO.selectPageList(DataBaseTableInfo.class, "information_schema.tables", "table_name as table_name,create_time as create_time,update_time as update_time,table_comment as table_comment", sql, "", paramMap);
        int total = commonDTO.selectCount("information_schema.tables", sql, paramMap);
        result.add("rows", rows);
        result.add("total", total);
        return result;
    }

    @ResponseBody
    @PostMapping("/imortTable")
    @Transactional(rollbackFor = {Exception.class}, isolation = Isolation.READ_UNCOMMITTED)
    public Object imortTable(@RequestBody List<DataBaseTableInfo> tableInfoList) {
        Result result = Result.okResult();
        for (DataBaseTableInfo tableInfo : tableInfoList) {
            codeGenLogic.imortTable(tableInfo);
        }
        return result;
    }

    @ResponseBody
    @PostMapping("/syncTable")
    @Transactional(rollbackFor = {Exception.class}, isolation = Isolation.READ_COMMITTED)
    public Object syncTable(@RequestBody Map<String, Object> params) {
        Result result = Result.okResult();
        String table_name = ConvertOp.convert2String(params.get("table_name"));
        codeGenLogic.syncTable(table_name);
        return result;
    }

    @ResponseBody
    @PostMapping("/createCode")
    public Object createCode(@RequestBody List<String> tableNameList) throws Exception {
        Result result = Result.okResult();
        String filePath = "codegenerate_" + CommonUtil.getNewGuid();
        String codeFolder = "tempfiles/codegen/" + filePath;
        byte[] data = codeGenLogic.createCode(codeFolder, tableNameList);
        FileUtil.writeFile(codeFolder + ".zip", data);
        result.add("obj", CommonUtil.getRootPath() + filePath + ".zip");
        return result;
    }

    @ResponseBody
    @PostMapping("/exportData")
    public Object exportData(@RequestBody List<String> tableNameList) throws Exception {
        Result result = Result.okResult();
        String fileid = codeGenLogic.exportData(tableNameList);
        result.add("fileid", fileid);
        return result;
    }

    @ResponseBody
    @PostMapping("/importData")
    public Object importData(@RequestParam("file") MultipartFile file, HttpServletRequest request) throws Exception {
        Result result = Result.okResult();
        String errormsg = codeGenLogic.importData(file.getInputStream());
        if (!StringUtil.isEmpty(errormsg)) {
            return Result.errorResult().setMsg(errormsg);
        }
        return result;
    }
}
